package com.tierstall.client.presenter;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.prefetch.Prefetcher;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.event.shared.HandlerManager;

import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.cellview.client.TreeNode;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

import com.tierstall.client.AppController;
import com.tierstall.client.event.GoToPageEvent;
import com.tierstall.client.event.LoginEvent;
import com.tierstall.client.service.WebServices;

import com.tierstall.client.view.AboutDialog;
import com.tierstall.client.view.ContentViewManager;
import com.tierstall.client.view.content.CV_TierMGMT;
import com.tierstall.client.view.content.CV_addGroup;
import com.tierstall.client.view.content.CV_showUsers;
import com.tierstall.client.view.content.CV_showUsers.CwConstants;
import com.tierstall.client.view.main.ContentWidget;

import com.tierstall.client.view.main.MainMenuTreeViewModel2;
import com.tierstall.client.view.main.MainMenuTreeViewModel2.Category;
import com.tierstall.client.view.main.ShowcaseResources;
import com.tierstall.client.view.main.ShowcaseShell;
import com.tierstall.client.view.main.ViewConstants;

import com.tierstall.shared.Logger;
import com.tierstall.shared.Page;
import com.tierstall.shared.UserDTO;

public class MainPresenter implements Presenter {

	private final WebServices rpcService;
	private final HandlerManager eventBus;
	private ShowcaseShell view;
	private String sessionId;
	private UserDTO currentUser;
	private final AppController appController;
	ViewConstants constants;

	private SingleSelectionModel<Page> selectionModel;
	private MainMenuTreeViewModel2 treeModel;
	private ContentViewManager viewManager;
	
	/**
	 * The static images used throughout the Showcase.
	 */
	public static final ShowcaseResources images = GWT
			.create(ShowcaseResources.class);

	// private boolean isUpdating = false;

	public MainPresenter(WebServices rpcServices, String sessionId,
			HandlerManager eventBus, AppController appController) {
		this.rpcService = rpcServices;
		this.eventBus = eventBus;
		this.sessionId = sessionId;
		this.appController = appController;
		
		// Initialize the constants.
		constants = new ViewConstants();
		// Initialize the Views
		viewManager = new ContentViewManager(constants);
	}

	public void go(final HasWidgets container) {
		Prefetcher.start();
		initalizeMainView();
		container.clear();
		container.add(view.asWidget());
		view.setContent(new CV_TierMGMT(constants));
		// setLoggedInUser();
	}

	private void initalizeMainView() {
		view = new ShowcaseShell(generateCellTree());
		handleMainMenu();

	}

	private MainMenuTreeViewModel2 generateCellTree() {
		// Create the application shell.
		selectionModel = new SingleSelectionModel<Page>();
		treeModel = new MainMenuTreeViewModel2(selectionModel);
		return treeModel;
	}

	private void handleMainMenu() {
		// Prefetch examples when opening the Category tree nodes.
		final List<Category> prefetched = new ArrayList<Category>();
		final CellTree mainMenu = view.getMainMenu();
		mainMenu.addOpenHandler(new OpenHandler<TreeNode>() {
			public void onOpen(OpenEvent<TreeNode> event) {
				Object value = event.getTarget().getValue();
				if (!(value instanceof Category)) {
					return;
				}

				Category category = (Category) value;
				if (!prefetched.contains(category)) {
					prefetched.add(category);
					Prefetcher.prefetch(category.getSplitPoints());
				}
			}
		});

		// Always prefetch.
		Prefetcher.start();

		// Change the history token when a main menu item is selected.
		selectionModel
				.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
					public void onSelectionChange(SelectionChangeEvent event) {
						Page selected = selectionModel
								.getSelectedObject();
						if (selected != null) {
							Logger.CLIENT_INFO("Selected Widget: "
									+ selected.id());
							eventBus.fireEvent(new GoToPageEvent(selected));
						}
					}
				});
		//
		// // Setup a history handler to reselect the associate menu item.
		// final ValueChangeHandler<String> historyHandler = new
		// ValueChangeHandler<
		// String>() {
		// public void onValueChange(ValueChangeEvent<String> event) {
		// // Get the content widget associated with the history token.
		// ContentWidget contentWidget = treeModel.getContentWidgetForToken(
		// event.getValue());
		// if (contentWidget == null) {
		// return;
		// }
		//
		// // // Expand the tree node associated with the content.
		// Category category = treeModel.getCategoryForContentWidget(
		// contentWidget);
		// TreeNode node = mainMenu.getRootTreeNode();
		// int childCount = node.getChildCount();
		// for (int i = 0; i < childCount; i++) {
		// if (node.getChildValue(i) == category) {
		// node.setChildOpen(i, true, true);
		// break;
		// }
		// }
		//
		// // Select the node in the tree.
		// selectionModel.setSelected(contentWidget, true);
		// }
		// };
	}

	public void onLoginClicked(String username, String password,
			final boolean save_session) {
		rpcService.getRpcSessionService().loginRequest(username, password,
				new AsyncCallback<String>() {
					@Override
					public void onSuccess(String session) {

					}

					public void onFailure(Throwable caught) {
						Window.alert("Error retrieving contact");
					}
				});
	}

	// private void setLoggedInUser() {
	// view.setLoginName(currentUser.getUsername());
	// }

	/**
	 * Get the token for a given content widget.
	 * 
	 * @return the content widget token.
	 */
	public static String getContentWidgetToken(ContentWidget content) {
		return getContentWidgetToken(content.getClass());
	}

	/**
	 * Get the token for a given content widget.
	 * 
	 * @return the content widget token.
	 */
	public static <C extends ContentWidget> String getContentWidgetToken(
			Class<C> cwClass) {
		String className = cwClass.getName();
		className = className.substring(className.lastIndexOf('.') + 1);
		return "!" + className;
	}

	public ShowcaseShell getMainView() {
		return view;
	}

	public MainMenuTreeViewModel2 getMainMenu() {
		return treeModel;
	}
	
	public ContentWidget getContentView(Page p) {
		return viewManager.getContentWidgetForToken(p);
	}
	
	public void setContentView(Page p) {
		getMainView().setContent(viewManager.getContentWidgetForToken(p));
	}
	
	public void setContentView(ContentWidget cw) {
		getMainView().setContent(cw);
	}

	public CwConstants getConstants() {
		return constants;
	}

	public void showNotPermittedDialog() {
		AboutDialog dlg = new AboutDialog();
		dlg.show();
		dlg.center();

	}
}
